#include "../include/camera.h"

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"


using namespace std;

camera::camera()
{
    //defualt initialize camera to 0,0,0
    camPos.Xpos = 0;
    camPos.Ypos = 0;
    ZPos = 0;
    transToHero = false;
}

camera::camera(float x, float y, float z, float cAngle)
{
    //set the camera position to x,y,z and set the viewing angle to cAngle
    camPos.Xpos = x;
    camPos.Ypos = y;
    ZPos = z;
    camAngle = cAngle;
    transToHero = false;
}

//update the camera position. Recieves the x and y of the mouse.
void camera::CamUpdate(int x, int y)
{
    //glutPassiveMotionFunc(getMouseCoord);
    //glutMotionFunc(processMouseActiveMotion);
    checkMouseBounds(x,y); //checks if the mouse is telling the camera to move
    glRotatef(-camAngle, 1.0f, 0.0f, 0.0f); //rotates the view to the negative of camAngle
	glTranslatef(-camPos.Xpos, camPos.Ypos, ZPos); //translates the matrix to the new camera position
}

/*void camera::getMouseCoord(int x, int y)
{

}*/

void camera::setScreenRatio(int w,int h)
{
    screenWidth = w;
    screenHeight = h;
}

//Checks if the mouse is telling the camera to move and updates camPos accordingly
void camera::checkMouseBounds(int x, int y)
{
    int leftBound = (screenWidth) / 8;
    int rightBound = (screenWidth * 7) / 8;
    int upperBound = (screenHeight) / 8;
    int lowerBound = (screenHeight * 7) / 8;

    if(x < leftBound)
        camPos.Xpos -= .1;
    if(x > rightBound)
        camPos.Xpos += .1;
    if(y < upperBound)
        camPos.Ypos -= .1;
    if(y > lowerBound)
        camPos.Ypos += .1;
}

void camera::zoom(int direction)
{
    if(direction > 0)
        if(ZPos > -15)
            ZPos--;

    if(direction < 0)
        if(ZPos < -8)
            ZPos++;
}
//Checks to see if the point needs to be drawn on screen
bool camera::IsInBounds(Position check, int groundspot){
    int tolerance = 2;
    Position TopLeft = getBound(0,0,groundspot);
    Position BottomRight = getBound(screenWidth,screenHeight,groundspot);
    return (check.Xpos < BottomRight.Xpos + tolerance &&
             check.Xpos > TopLeft.Xpos - tolerance &&
             check.Ypos > BottomRight.Ypos - tolerance &&
              check.Ypos < TopLeft.Ypos + tolerance);
}

//Returns the Pos of the Thing at ground height
Position camera::getBound(int x, int y,int groundspot){
    GLint viewport[4];
    GLdouble mvmatrix[16], projmatrix[16];
    GLint realy; /* OpenGL y coordinate position */
    GLdouble wx, wy, wz, wx2,wy2,wz2; /* returned world x, y, z coords */
    GLdouble dx, dy, dz;

    glGetIntegerv (GL_VIEWPORT, viewport);
    glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
    glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
    /* note viewport[3] is height of window in pixels */
    realy = viewport[3] - (GLint) y - 1;

    gluUnProject ((GLdouble) x, (GLdouble) realy, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

    gluUnProject ((GLdouble) x, (GLdouble) realy, 1.0, mvmatrix, projmatrix, viewport, &wx2, &wy2, &wz2);


    Position Bound = Position((float)(wx + (wx2 - wx) * (groundspot - wz) / (wz2 - wz)),
                          (float)(wy + (wy2 - wy) * (groundspot - wz) / (wz2 - wz)));

    return Bound;
}


void camera::ReturnToOrigin(Position p)
{
    camPos.Xpos = p.Xpos;
    camPos.Ypos = -p.Ypos;
}

camera::~camera()
{

}
